<!DOCTYPE html>
<HTML>
<HEAD>
	<TITLE> CKNote </TITLE>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<link rel="stylesheet" href="css/demo.css" type="text/css">
	<link rel="stylesheet" href="css/zTreeStyle/zTreeStyle.css" type="text/css">
	<script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
	<script type="text/javascript" src="js/jquery.ztree.core-3.3.js"></script>
	<script type="text/javascript" src="js/jquery.ztree.excheck-3.3.js"></script>
	<script type="text/javascript" src="js/jquery.ztree.exedit-3.3.js"></script>
	<SCRIPT type="text/javascript">
		var initFinished = false;
		var setting = {
			view: {
				selectedMulti: false
			},
			async: {
				enable: true,
				//url:"http://www.ztree.me/v3/demo/en/asyncData/getNodes.php",
				url:"/testjson",
				autoParam:["docId", "folderId", "name=n", "level=lv", "action", "param"],		//folderId is not always reliable
				otherParam:{"otherParam":"zTreeAsyncTest"},
				dataFilter: filter
			},
			callback: {
				beforeClick: beforeClick,
				beforeAsync: beforeAsync,
				onAsyncError: onAsyncError,
				onAsyncSuccess: onAsyncSuccess,

				onRightClick: OnRightClick				//context menu
			}
		};

		var zNodes =[{ id:1, pId:0, name:"retrieving notes ...", open:true,}];
			

		function filter(treeId, parentNode, childNodes) {
			if (!childNodes) return null;
			if(childNodes.length==0)	//no items
				return null;
			//pNodeInfo = childNodes.pop();
			pNodeInfo = childNodes.shift();	//the first element used to update the parentNode
			if(pNodeInfo.docId!=null){			//if docId is null, ignore (dummy node)
				// alert("docId is " + pNodeInfo.docId);
				if(parentNode == null)
					return null;
				
				if(pNodeInfo.docId=='deleted') {
					alert('this node is deleted !');
					zTree.removeNode(parentNode);		//also valid if parentNode is null
					return null;				//ok ??
				}
				parentNode.docId = pNodeInfo.docId;
				parentNode.folderId = pNodeInfo.folderId;
				parentNode.name = pNodeInfo.name;
				parentNode.isParent = pNodeInfo.isParent;
				parentNode.attachments = pNodeInfo.attachments;
				parentNode.subNodes = pNodeInfo.subNodes;			//the same with isParent (for update in onAsyncSuccess)
				// zTree.updateNode(parentNode);	//update this node //here unuseful, because zTree add Nodes followed
				//update the node in onAsyncSuccess()
			}
			
			for (var i=0, l=childNodes.length; i<l; i++) {
				childNodes[i].name = childNodes[i].name.replace(/\.n/g, '.');
			}
			return childNodes;
		}

		function beforeClick(treeId, treeNode) {
			// alert(treeNode.docId);
			if(treeNode.docId=='root') {
				// $("#editframe",parent.document.body).attr("src","/about")
				$("#editframe",parent.document).attr("src","/about");
				return true;
			}
			editlink = "https://docs.google.com/document/d/"+treeNode.docId+"/edit"
			$("#editframe",parent.document).attr("src",editlink)
			return true;
		}
		var log, className = "dark";
		function beforeAsync(treeId, treeNode) {
			className = (className === "dark" ? "":"dark");
			showLog("[ "+getTime()+" beforeAsync ]&nbsp;&nbsp;&nbsp;&nbsp;" + ((!!treeNode && !!treeNode.name) ? treeNode.name : "root") );
			return true;
		}
		function onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) {
			var icoObj = $("#" + treeNode.tId + consts.id.ICON);
			icoObj.attr({"style":"", "class":"button remove"});
			
			alert("Async Error !");
			showLog("[ "+getTime()+" onAsyncError ]&nbsp;&nbsp;&nbsp;&nbsp;" + ((!!treeNode && !!treeNode.name) ? treeNode.name : "root") );
		}
		function onAsyncSuccess(event, treeId, treeNode, msg) {
			if(treeNode == null) {
				// alert("treeNode is null (root)");
				return;
			}
			// alert("async success");
			
			//update the selected node
			//even if the returned childNodes is [], the icon remain to be a folder (with no children), so must update the node
			treeNode.isParent = treeNode.subNodes;
			zTree.updateNode(treeNode);

			initFinished = true;

			// alert(msg);
			// nodeconfig = eval(msg);							//deal in filter()
			// treeNode.isParent = (nodeconfig.length>0);
			// zTree.updateNode(treeNode);
			// return;

			//alert("isParent "+treeNode.isParent);

			/* for example
			[
				{"isParent": false, "folderId": "1exyE55ICmpu4Agv4U3yE8-UUkDE-7xsE4f0giBy46vA", "docId": "1exyE55ICmpu4Agv4U3yE8-UUkDE-7xsE4f0giBy46vA", "name": "test2", "attachments": false},
				{"isParent": false, "folderId": "1pDKW3P9xLh2CIJ5dIQ78OvnezmPN_nbADA84TXFqu1Y", "docId": "1pDKW3P9xLh2CIJ5dIQ78OvnezmPN_nbADA84TXFqu1Y", "name": "emptydoc", "attachments": false},
				{"isParent": false, "folderId": "14T0v8CIu5udR2sYcxS7tnUYFaPZ-Inuz28S8_W5uOoo", "docId": "14T0v8CIu5udR2sYcxS7tnUYFaPZ-Inuz28S8_W5uOoo", "name": "test1", "attachments": false}
			]
			//empty data
			[]
			*/
			showLog("[ "+getTime()+" onAsyncSuccess ]&nbsp;&nbsp;&nbsp;&nbsp;" + ((!!treeNode && !!treeNode.name) ? treeNode.name : "root") );
		}

		function showLog(str) {
			if (!log) log = $("#log");
			log.append("<li class='"+className+"'>"+str+"</li>");
			if(log.children("li").length > 8) {
				log.get(0).removeChild(log.children("li")[0]);
			}
		}
		function getTime() {
			var now= new Date(),
			h=now.getHours(),
			m=now.getMinutes(),
			s=now.getSeconds(),
			ms=now.getMilliseconds();
			return (h+":"+m+":"+s+ " " +ms);
		}
		
////////////////////////////////////////////////////////////////////////////////////////////////////
// func for context menu

		function OnRightClick(event, treeId, treeNode) {
			
			if(initFinished==false) {			//not init
				showRMenu("init", event.clientX, event.clientY);
			} else if(!treeNode) {				//in the blank area
				zTree.cancelSelectedNode();
				// showRMenu("blankarea", event.clientX, event.clientY);
				return false;
			} else if(treeNode.level==0) {		//root node
				zTree.selectNode(treeNode);
				showRMenu("root", event.clientX, event.clientY);
			} else {
				zTree.selectNode(treeNode);
				showRMenu("node", event.clientX, event.clientY);
			}
			
			// if (!treeNode && event.target.tagName.toLowerCase() != "button" && $(event.target).parents("a").length == 0) {
			// 	zTree.cancelSelectedNode();
			// 	showRMenu("root", event.clientX, event.clientY);
			// } else if (treeNode && !treeNode.noR) {
			// 	zTree.selectNode(treeNode);
			// 	showRMenu("node", event.clientX, event.clientY);
			// }
		}


		function showRMenu(type, x, y) {
			// $("#rMenu ul").show();
			$("#rMenu ul li").hide();
			if (type=="init") {
				$("#m_refresh_wholenotes").show();
			} else if(type=="blankarea") {
				// $("#m_refresh_all").show();
				return false;
			} else if(type=="root") {
				$("#m_add_sub").show();
				$("#m_rename").show();
				$("#m_refresh_cur").show();
				$("#m_refresh_wholenotes").show();
			} else if(type=="node") {
				$("#m_add_sub").show();
				$("#m_rename").show();
				$("#m_del").show();
				$("#m_refresh_cur").show();
				$("#m_refresh_allsubnodes").show();
			}
			
			rMenu.css({"top":y+"px", "left":x+"px", "visibility":"visible"});

			// $("body").bind("mousedown", onBodyMouseDown);
			// $(document).bind("mousedown", onBodyMouseDown);
			$(document).bind("mousedown", onBodyMouseDown);
		}
		function hideRMenu() {
			if (rMenu) rMenu.css({"visibility": "hidden"});
			// $("body").unbind("mousedown", onBodyMouseDown);
			$(document).unbind("mousedown", onBodyMouseDown);
		}
		function onBodyMouseDown(event){
			if (!(event.target.id == "rMenu" || $(event.target).parents("#rMenu").length>0)) {
				rMenu.css({"visibility" : "hidden"});
			}
		}
////////////////////////////////////////////////////////////////////////////////////////////////////
		function addSubNode() {
			hideRMenu();
			var selNode = zTree.getSelectedNodes()[0];
			if (selNode) {
				// newNode.checked = zTree.getSelectedNodes()[0].checked;
				//zTree.addNodes(zTree.getSelectedNodes()[0], newNode);
				// alert(selNode.folderId);			// put this value to the server
				selNode.param = prompt("please input a node name:");
				if(!selNode.param) return;
				selNode.action = "addSubNode";
				//if(selNode.isParent==false)
				selNode.isParent = true;	//force to parent node, otherwise will not reAsync (re-set this attr in onAsyncSuccess)
				zTree.reAsyncChildNodes(selNode, 'refresh', false);
				//selNode.isParent = false;		//the actual value according to the return data
				selNode.param = "";
				selNode.action = "";

				// the select the new node, and open it in the editor
				//selNode.children
				//selNode.children[0]
				
				//selectedNode.
				
				//zTree.addNodes(null, { name:"newNode"});
			} else {															//not select any node
				alert("you not select a node, add node to root !");
				zTree.addNodes(null, newNode);
			}
		}

		function renameRequest(setting, node, newname) {
			var icoObj = $("#" + node.tId + consts.id.ICON);
			icoObj.attr({"style":"", "class":"button ico_loading"});
			$.ajax({
				contentType: setting.async.contentType,
				type: setting.async.type,
				url: $.fn.zTree._z.tools.apply(setting.async.url, [setting.treeId, node], setting.async.url),
				data: "action=renameNode&docId="+node.docId+"&param="+newname,
				dataType: setting.async.dataType,
				success: function(msg) {
					var newNodes = [];
					try {
						if (!msg || msg.length == 0) {
							newNodes = [];
						} else if (typeof msg == "string") {
							newNodes = eval("(" + msg + ")");
						} else {
							newNodes = msg;
						}
					} catch(err) {}
					view.setNodeLineIcos(setting, node);
					// alert(msg);
					// alert(newNodes[0].name);
					newConfig = newNodes[0]
					
					node.docId = newConfig.docId;
					node.folderId = newConfig.folderId;
					node.name = newConfig.name;
					node.isParent = newConfig.isParent;
					node.attachments = newConfig.attachments;
					node.subNodes = newConfig.subNodes;			//the same with isParent (for update in onAsyncSuccess)
					
					setting.treeObj.trigger(consts.event.ASYNC_SUCCESS, [setting.treeId, node, msg]);	
				},
				error: function(XMLHttpRequest, textStatus, errorThrown) {
					view.setNodeLineIcos(setting, node);
					setting.treeObj.trigger(consts.event.ASYNC_ERROR, [setting.treeId, node, XMLHttpRequest, textStatus, errorThrown]);
				}
			});
		}
			
		function renameNode() {
			hideRMenu();
			var selNode = zTree.getSelectedNodes()[0];
			if (selNode==null) {
				alert("you not select a node !");				//the refresh current node should not display if not select a node
				return;
			}
			newname = prompt("please input a new name:", selNode.name);
			
			if(!newname || newname==selNode.name)				// input nothing or press cancel (get '' or null) or not change
				return;
			// selNode.action = "renameNode";
			// selNode.param = newname;
			// selNode.isParent = true;	//force to parent node, otherwise will not reAsync (re-set this attr in onAsyncSuccess())
			// zTree.reAsyncChildNodes(selNode, 'append', true);	//not auto expand		//not valid
			// //selNode.isParent = false;		//the actual value according to the return data
			// selNode.param = "";
			// selNode.action = "";
			renameRequest(zTree.setting, selNode, newname);
		}

		function removeNode() {
			hideRMenu();
			var selNode = zTree.getSelectedNodes()[0];
			if (selNode==null) {
				alert("you not select a node !");				//the refresh current node should not display if not select a node
				return;
			}
			r=confirm("Really delete this node ?");
			if (r!=true){
				return;
			}
			selNode.action = "removeNode";
			selNode.isParent = true;	//force to parent node, otherwise will not reAsync (re-set this attr in onAsyncSuccess())
			zTree.reAsyncChildNodes(selNode, 'refresh', true);	//not auto expand
			//selNode.isParent = false;		//the actual value according to the return data
			selNode.action = "";
		}


		function refreshCurNode() {
			hideRMenu();
			var selNode = zTree.getSelectedNodes()[0];
			if (selNode==null) {
				alert("you not select a node !");				//the refresh current node should not display if not select a node
				return;
			}
			selNode.action = "refreshCurNode";
			selNode.isParent = true;	//force to parent node, otherwise will not reAsync (re-set this attr in onAsyncSuccess())
			zTree.reAsyncChildNodes(selNode, 'refresh', true);	//not auto expand
			//selNode.isParent = false;		//the actual value according to the return data
			selNode.action = "";
		}
		function refreshAllSubNodes() {
			hideRMenu();
			var selNode = zTree.getSelectedNodes()[0];
			if (selNode==null) {
				// alert("you not select a node !");
				selNode = rootNode;
			}
			selNode.action = "refreshAllSubNodes";
			selNode.isParent = true;	//force to parent node, otherwise will not reAsync (re-set this attr in onAsyncSuccess())
			zTree.reAsyncChildNodes(selNode, 'refresh', true);	//not auto expand
			//selNode.isParent = false;		//the actual value according to the return data
			selNode.action = "";
		}

		// function removeTreeNode() {
		// 	hideRMenu();
		// 	var nodes = zTree.getSelectedNodes();
		// 	if (nodes && nodes.length>0) {
		// 		if (nodes[0].children && nodes[0].children.length > 0) {
		// 			var msg = "If you delete this node will be deleted along with sub-nodes. \n\nPlease confirm!";
		// 			if (confirm(msg)==true){
		// 				zTree.removeNode(nodes[0]);
		// 			}
		// 		} else {
		// 			zTree.removeNode(nodes[0]);
		// 		}
		// 	}
		// }
		// function checkTreeNode(checked) {
		// 	var nodes = zTree.getSelectedNodes();
		// 	if (nodes && nodes.length>0) {
		// 		zTree.checkNode(nodes[0], checked, true);
		// 	}
		// 	hideRMenu();
		// }
		// function resetTree() {
		// 	hideRMenu();
		// 	$.fn.zTree.init($("#treeDemo"), setting, zNodes);
		// }


////////////////////////////////////////////////////////////////////////////////////////////////////
		function bindRMenuFuncs() {
			$("#m_add_sub").click(addSubNode);
			$("#m_rename").click(renameNode);
			$("#m_del").click(removeNode);
			$("#m_refresh_cur").click(refreshCurNode);
			$("#m_refresh_allsubnodes").click(refreshAllSubNodes);
			$("#m_refresh_wholenotes").click(refreshAllSubNodes);
		}
////////////////////////////////////////////////////////////////////////////////////////////////////
		var zTree, rMenu, rootNode;
		$(document).ready(function(){
			// $.fn.zTree.init($("#notestree"), setting);
			$.fn.zTree.init($("#notestree"), setting, zNodes);
			consts = $.fn.zTree.consts;
			view = $.fn.zTree._z.view;
			
			zTree = $.fn.zTree.getZTreeObj("notestree");
			
			rootNode = zTree.getNodeByParam("level", 0, null);	//get the root node		//got an array ???
			rootNode.action = "inittree";
			rootNode.isParent = true;	//force to parent node, otherwise will not reAsync (re-set this attr in onAsyncSuccess())
			zTree.reAsyncChildNodes(rootNode, 'refresh', false);	//auto expand
			rootNode.action = "";
		
			// $("#refreshNode").bind("click", {type:"refresh", silent:false}, refreshNode);
			// $("#refreshNodeSilent").bind("click", {type:"refresh", silent:true}, refreshNode);
			// $("#addNode").bind("click", {type:"add", silent:false}, refreshNode);
			// $("#addNodeSilent").bind("click", {type:"add", silent:true}, refreshNode);
			rMenu = $("#rMenu");
			bindRMenuFuncs();
		});

</script>

<style type="text/css">
div#rMenu {position:absolute; visibility:hidden; top:0; background-color: #555;text-align: left;padding: 2px;}
div#rMenu ul li{
	margin: 1px 0;
	padding: 0 5px;
	cursor: pointer;
	list-style: none outside none;
	background-color: #DFDFDF;
}
</style>

</head>

<!-- my style -->
<style>
 #notesview{
	  height:1000px;
	  border:1px solid #000000;
  }

  #notesview #left_panel{
  height:100%;
  border:1px solid #f0f0f0;
  width:25%; float:left;display:block;
	  background-color: #f0f6e4;
  }
  
  #notesview #right_panel{
  height:100%;
  border:1px solid #cccccc;

  width:74%; float:right; display:block;
  }
</style>

<body>

  <ul id="notestree" class="ztree"></ul>
	
  <!-- context menu -->
<div id="rMenu">
	<ul>
		<li id="m_add_sub">Add Sub Node</li>
		<li id="m_rename">Rename Node</li>	
		<li id="m_del">Delete Node</li>
		<li id="m_refresh_cur">Refresh Current Node</li>
		<li id="m_refresh_allsubnodes">Refresh All Sub Nodes</li>
		<li id="m_refresh_wholenotes">Refresh Whole Notes</li>
	</ul>
</div>


</body>
</html>
